﻿using iTextSharp.text.pdf;
using iTextSharp.text;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using TianYu.Core.Common.Security;
using TianYu.Core.Common;

namespace TianYu.Core.Pdf
{
    public class PdfDocumentService : IPdfDocumentService
    {
        private readonly PdfTemplateOptions _pdfTemplateOptions;
        private static Dictionary<string, PdfDocumentContent> templateObject;

        public PdfDocumentService(IOptions<PdfTemplateOptions> options)
        {
            _pdfTemplateOptions = options.Value;
        }



        public async Task<byte[]> GetPDFDocument(List<PdfTemplateData> list)
        {
            if (!list.Any()) return default;

            using (MemoryStream stream = new MemoryStream())
            {
                var document = new Document();
                try
                {
                    PdfWriter writer = PdfWriter.GetInstance(document, stream);

                    //设置文档属性
                    document.AddAuthor(_pdfTemplateOptions.Author);
                    document.AddCreationDate();
                    document.AddKeywords(_pdfTemplateOptions.Keywords);
                    document.AddCreator(_pdfTemplateOptions.Creator);
                    document.AddTitle(_pdfTemplateOptions.Title);
                    document.AddSubject(_pdfTemplateOptions.Subject);
                    document.AddProducer();
                    document.Open();

                    foreach (var item in list)
                    {
                        var pdfDocumentContent = GetTemplateObject(item.LabelTemplate);

                        document.SetPageSize(new Rectangle(pdfDocumentContent.Width, pdfDocumentContent.Height));

                        var dataObj = JObject.FromObject(item.ContentData);

                        var content = new PdfTemplateContent(document, dataObj, writer, pdfDocumentContent.Height);

                        if (string.IsNullOrWhiteSpace(pdfDocumentContent.Repeater))
                        {
                            DrawPage(document, content, pdfDocumentContent.Elements);
                        }
                        else
                        {
                            if (dataObj.ContainsKey(pdfDocumentContent.Repeater))
                            {
                                foreach (var item2 in dataObj[pdfDocumentContent.Repeater])
                                {
                                    content.JToken = item2;
                                    DrawPage(document, content, pdfDocumentContent.Elements);
                                }
                            }
                            else
                            {
                                DrawPage(document, content, pdfDocumentContent.Elements);
                            }
                        }
                    }
                }
                catch (TYBaseException ex) { throw ex; }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (document.IsOpen())
                    {
                        try
                        {
                            document.Close();
                        }
                        catch (Exception)
                        {
                            if (document.IsOpen())
                            {
                                document.Add(new Paragraph(" "));
                                document.Close();
                            }
                        }
                    }
                }
                return await Task.FromResult(stream.ToArray());
            }
        }

        /// <summary>
        /// 画每一页
        /// </summary>
        /// <param name="document"></param>
        /// <param name="content"></param>
        private void DrawPage(Document document, PdfTemplateContent content, List<IPdfElement> elements)
        {
            document.NewPage();
            foreach (var item in elements)
            {
                item.Draw(content);
            }
        }
        /// <summary>
        /// 获取模板对象
        /// </summary>
        /// <param name="labelTemplateID">标签模板ID</param>
        /// <returns></returns>
        private PdfDocumentContent GetTemplateObject(string labelTemplate)
        {
            if (labelTemplate.IsNullOrWhiteSpace())
            {
                throw new TYBaseException("标签模板不能为空");
            }

            var key = MD5Helper.MD5String(labelTemplate);

            if (templateObject == null) templateObject = new Dictionary<string, PdfDocumentContent>();

            if (templateObject.ContainsKey(key))
            {
                return templateObject[key];
            }
            else
            {
                var pdfDocumentContent = ElementTools.CreateElement(labelTemplate);

                //缓存模板解析对象  
                templateObject.Add(key, pdfDocumentContent);

                return pdfDocumentContent;
            }
        }
    }
}
